package com.zkadmin.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.zkoss.zul.DefaultTreeModel;
import org.zkoss.zul.DefaultTreeNode;

import com.mysema.query.types.Predicate;
import com.zkadmin.entity.SysResource;
import com.zkadmin.entity.SysRole;
import com.zkadmin.repository.SysResourceRepository;
import com.zkadmin.service.SysResourceService;

@Service("sysResourceService")
public class SysResourceServiceImpl implements SysResourceService {
	@Autowired
	private SysResourceRepository repository;

	@Override
	public SysResource save(SysResource resource) {
		return repository.save(resource);
	}

	@Override
	public Page<SysResource> paging(Predicate predicate, Pageable pageable) {
		return repository.findAll(predicate, pageable);
	}

	@Override
	public Page<SysResource> findGrouped(Pageable pageable) {
		return repository.findGrouped(pageable);
	}

	@Override
	public SysResource createPermission(SysResource permission) {
		return repository.save(permission);
	}

	@Override
	public SysResource findByName(String name) {
		return repository.findByName(name);
	}

	@Override
	public SysResource findByCode(String code) {
		return repository.findByCode(code);
	}

	@Override
	public SysResource findByPermission(String permission) {
		return repository.findByPermission(permission);
	}

	@Override
	public List<SysResource> findByCodeLike(String code) {
		return repository.findByCodeLike(code);
	}

	@Override
	public void delete(Long resourceId) {
		SysResource resource = repository.findOne(resourceId);
		Set<SysRole> roles = resource.getRoles();
		for (SysRole role : roles) {
			role.getResources().clear();
		}
		repository.delete(resource);
	}

	@Override
	public List<SysResource> getRootResources() {
		return getResources(null);
	}

	private List<SysResource> getResources(final String code) {
		StringBuilder codes = new StringBuilder();
		String likeCode = "";
		int codeLen = 2;
		if (code != null) {
			codeLen = likeCode.length() + 2;
			likeCode = code;
		}

		if (codeLen % 2 == 0) {
			for (int i = 0; i < codeLen / 2; i++) {
				codes.append("__");
			}
		}
		return repository.findByCodeLike(likeCode + codes);
	}

	private List<DefaultTreeNode<SysResource>> getResourceTreeNodes(List<SysResource> resources) {
		List<DefaultTreeNode<SysResource>> results = new ArrayList<DefaultTreeNode<SysResource>>();
		for (SysResource resource : resources) {
			List<DefaultTreeNode<SysResource>> subResources = getResourceTreeNodes(getResources(resource.getCode()));
			results.add(subResources.isEmpty() ? new DefaultTreeNode<SysResource>(resource) : new DefaultTreeNode<SysResource>(resource, subResources));
		}
		return results;
	}

	@Override
	public DefaultTreeModel<SysResource> getResourceTreeModel(boolean isMultiple) {
		DefaultTreeModel<SysResource> treeModel = new DefaultTreeModel<SysResource>(new DefaultTreeNode<SysResource>(null, getResourceTreeNodes(getRootResources())));
		treeModel.setMultiple(isMultiple);
		return treeModel;
	}
}
